Skip to content

fix(web): show message copy buttons on touch devices - #11020

Merged
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:fix/copy-button-touch-2804
Sep 10, 2026
Merged

fix(web): show message copy buttons on touch devices#11020
maria-rcks merged 1 commit into
pingdotgg:mainfrom
maria-rcks:fix/copy-button-touch-2804

Conversation

@maria-rcks

@maria-rcks maria-rcks commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

On mobile web the copy button on user and assistant messages was invisible: both action rows are opacity-0 and only reveal on hover/focus-within, neither of which a touch browser produces, so there was no discoverable way to copy an agent response.

Both rows now stay at opacity-100 under @media (pointer: coarse) using the pointer-coarse: Tailwind variant already used in ChatComposer.tsx and KeybindingsSettings.tsx. Hover/pointer-fine behavior is untouched, so desktop still reveals the row on hover. The timestamp and the revert button share those rows and become visible on touch too, which is the same discoverability win.

Verified: vp run --filter @t3tools/web typecheck passed with no errors; vp lint apps/web/src/components/chat/MessagesTimeline.tsx passed (only pre-existing warnings on unrelated lines); vitest run src/components/chat/MessagesTimeline.test.tsx src/components/chat/MessagesTimeline.logic.test.ts passed 147/147; compiled pointer-coarse:opacity-100 through the repo's Tailwind 4.3.3 and confirmed it emits @media (pointer: coarse) { .pointer-coarse\:opacity-100 { opacity: 100% } }. No test added: the change is class-only and AGENTS.md rules out tests that assert rendered attributes.

Out of scope: apps/mobile is React Native and has its own copy affordance, and the timeline minimap / turn-nav arrows in the same file are already gated to pointer: fine on purpose.

Fixes #2804

UI evidence: unverified. The browser preview host was unavailable in this session, so the changed interaction was not exercised in a real client. Scoped tests, typecheck, and lint pass; a reviewer should exercise the interaction locally before merge.

Done by Claude Opus 5 (1M context) in Claude Code.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Message timestamps and copy controls now remain visible on touch devices instead of requiring hover or focus.

On mobile web the user- and assistant-message action rows were only
revealed by hover or focus-within, so the copy button was invisible and
undiscoverable on a phone. Both rows now stay at full opacity under
`@media (pointer: coarse)` via the `pointer-coarse:` variant already
used elsewhere in apps/web. Hover devices are unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Sep 10, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at f4f791e

Macroscope's review found this PR approvable — This is a narrowly scoped web UI fix that exposes existing message copy controls on coarse-pointer devices. It changes only responsive visibility styling in one component and has no broader runtime, API, configuration, or deployment impact.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: cea693d8-2389-4e5c-b6f4-021c0a3c0455

📥 Commits

Reviewing files that changed from the base of the PR and between b7b3ef1 and f4f791e.

📒 Files selected for processing (1)
  • apps/web/src/components/chat/MessagesTimeline.tsx

Included review availability: Your plan provides up to 10 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

The message metadata rows for user and assistant messages now use full opacity on coarse-pointer devices. This keeps timestamps and copy controls visible on touch devices.

Changes

Mobile message metadata

Layer / File(s) Summary
Coarse-pointer metadata visibility
apps/web/src/components/chat/MessagesTimeline.tsx
User and assistant metadata rows now apply opacity-100 on coarse-pointer devices, in addition to focus and hover visibility rules.

Estimated code review effort: 1 (Trivial) | ~2 minutes

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to f4f79

Message copy controls, timestamps, and related actions are now visible on touch devices while desktop interaction behavior remains unchanged. No current merge-blocking risk is identified.

Suggested reviewers: juliusmarminge, t3dotgg

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: showing message copy buttons on touch devices.
Description check ✅ Passed The description explains the problem, implementation, behavior on desktop and touch devices, validation performed, and scope. UI evidence and the template checklist are not included, but the descripti…
Linked Issues check ✅ Passed The class updates make assistant and user message action rows visible on coarse-pointer devices, which provides the discoverable mobile copy action required by issue [#2804]. Desktop hover and focus b…
Out of Scope Changes check ✅ Passed The change is limited to two relevant class updates in MessagesTimeline.tsx. The additional visibility of timestamps and revert controls is a direct consequence of the shared action rows and remains w…
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@maria-rcks
maria-rcks merged commit 385cc0a into pingdotgg:main Sep 10, 2026
21 checks passed
aorwall added a commit to aorwall/t3code that referenced this pull request Sep 10, 2026
Merges `pingdotgg/t3code` `2a3035353..0f602b3` (16 commits) into the
fork.

- **Landed:** 283 files (`HEAD^1..HEAD`) against 277 in the upstream
range — `merge-stats.mjs` reports an exact 277/277 file match, so
nothing in the range was dropped and nothing extra came in. The six over
are three typecheck fixes and three fork docs, both listed below. Fork
delta 733 files (`HEAD^2..HEAD`).
- **Conflicts:** 6 files, all on one upstream feature (pingdotgg#10839, linking
several pull requests to a thread). Resolutions in
`docs/fork/upstream-merge-log.md`.
- **Sweep:** 13 owned-concern hits, all `infra/relay/**`
FCM/Android-push files under the decided-out `cloud-relay-connect`
concern. Inherited in tree, adopted by nothing.
- **Unsupported methods:** 0 ADD, 0 DROP — no
`packages/contracts/src/rpc.ts` edit needed.

## What upstream shipped

### Usable as-is against Moatless

Pure client work, no backend involvement — these are live the moment
this merges.

- **pingdotgg#11020** message copy buttons show on touch devices.
- **pingdotgg#11018** middle-click pastes in the terminal on Linux.
- **pingdotgg#10869** expanded images zoom and pan.
- **pingdotgg#11002** the composer uses the available space for model names.
- **pingdotgg#10981** duplicate tool-call commands can be expanded independently.
- **pingdotgg#10947** provider settings grow a bulk model toggle.
- **pingdotgg#10609** the PR list's diff counts return to the top right.
- **pingdotgg#11022** remote projects open in Zed
(`packages/contracts/src/editor.ts` plus the desktop shell — the fork
ships both).
- **pingdotgg#10998 / pingdotgg#10983 / pingdotgg#10964** three Android glass/overlap fixes in
`apps/mobile`.

### Unsupported in Moatless — needs backend implementation

- **pingdotgg#10839 — several pull requests per thread.** This is the substantive
decision in the merge. Upstream now carries `thread.pullRequests:
ThreadPullRequestLink[]`, `packages/shared/src/threadPullRequests.ts`,
and a `ThreadPullRequestBadgeControl` pill with its own `pull-requests`
stack tab. That is exactly the equivalent the fork's
`task-bound-pull-request` convergence entry said to re-home its `+N`
menu onto — but it cannot be re-homed yet: Moatless serves no
`pullRequests` array on a thread and does not advertise the new
`threadPullRequests` capability, so upstream's badge would resolve to
nothing and paint an empty pill over a working one. Taking `theirs`
would have silently deleted live fork behaviour.

**Resolution:** upstream's implementation landed whole, and the two
presentations are switched on `useSupportsMultiplePullRequests` —
upstream's badge and stack where the server advertises the capability,
the fork's binding-derived pill and `+N` menu where it does not.
Additive, no prop threading, and it re-homes itself the day the backend
advertises. `docs/fork/inventory.json` and `docs/fork/gaps.md` are
updated with the switch and with the exact deletion list for when that
happens.

**To close it:** serve `thread.pullRequests` on
`OrchestrationThread`/`OrchestrationThreadShell` from `task_bindings`,
and report `capabilities.threadPullRequests: true`.

- **pingdotgg#10870 — find threads by linked pull request.** Search terms come
off the same `thread.pullRequests` array, so sidebar and command-palette
search by PR number/URL match nothing here until the array is served.
Closes with pingdotgg#10839.

- **pingdotgg#10875 — navigate, merge and rebase GitHub stacks.** Adds two RPC
methods, `pullRequests.stack` and `pullRequests.linkedThreads`, which
the Moatless backend does not dispatch. Both are already covered by the
shared `PullRequestRpcError` union, so the client decodes the refusal
correctly and the stack UI stays inert — no contract change needed.
Implementing the two methods is what turns it on.

- **pingdotgg#10416 — Android agent notifications and ongoing activity.** Rides
FCM through `infra/relay`, which is part of the decided-out
`cloud-relay-connect` concern (being removed with Clerk). Inherited in
tree, not adopted.

### Backend behaviour worth reproducing in Moatless

- **pingdotgg#11007 — recent PR reads survive a server restart.** Upstream added
`apps/server/src/pullRequest/PullRequestReadCache.ts`, persisting which
pull requests a user has already read so a restart does not re-mark the
whole list unread. Moatless owns this surface itself, so nothing in this
repository holds it open — recorded so whoever touches the backend's PR
read state knows the answer exists upstream.

## Verification

`verify.mjs`, seven of eight green: `duplicate-adds`, `tripwires`,
`resolution-check`, `unsupported-methods`, `fmt:check`, `lint`,
`typecheck`.

`test` is red on `@t3tools/desktop` alone —
`scripts/browser-secret-native.test.mjs > bundled libsecret helper`
fails to compile because `libsecret-1` is not installed in this sandbox.
**Pre-existing environment gap, not merge-introduced:** it is already an
entry in `docs/fork/gaps.md`, and `git diff --name-only HEAD^1 HEAD |
grep browser-secret` is empty. 100 of 102 desktop files pass. Four
packages did not finish under `vp run -r test` (`@t3tools/mobile`, `t3`,
`@t3tools/web`, `t3code-relay`) and all four pass when run alone, which
is parallel load rather than the merge.

Three typecheck failures were fixed in the merge commit, all fork-only
web code that upstream's widened shared types reached:
`sandboxControl.placement.test.tsx` needed the two new `RightPanelTabs`
props, and `useSandboxAvailability.ts` / `useSandboxDetail.ts` needed
`isSuccess` threaded through now that `EnvironmentQueryView` carries it.

Nothing is unresolved.

---
Moatless task:
https://moatless.soaplabstest.com/tasks/db1b3cbe-4401-441b-bbec-6b0c725c93ce
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Sep 10, 2026
## What's Changed
* fix(web): restore pr list diff counts to the top right by @maria-rcks in pingdotgg/t3code#10609
* fix(web): show message copy buttons on touch devices by @maria-rcks in pingdotgg/t3code#11020
* fix(web): middle-click pastes in the terminal on Linux by @maria-rcks in pingdotgg/t3code#11018
* fix(editors): open remote projects in Zed by @maria-rcks in pingdotgg/t3code#11022
* feat: add blue and orange diff color palette by @maria-rcks in pingdotgg/t3code#10671
* fix(server): resolve project identity before legacy pr relinks by @t3-code[bot] in pingdotgg/t3code#11045


**Full Changelog**: pingdotgg/t3code@v0.0.41-nightly.20260910.1473...v0.0.41-nightly.20260910.1486

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.41-nightly.20260910.1486
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Copy action for assistant responses is not discoverable or usable on mobile web

1 participant